﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection.Impl;
using StyleMVVM.Logging;

namespace StyleMVVM.DependencyInjection
{
	/// <summary>
	/// This is used to share an export per request,  in a client that mean it will only be shared per that injection,
	///  in the context of MVC that mean per HTTP request, and in WCF that means per call.
	/// </summary>
	public class SharedPerRequestContainer : ILifeCycleContainer
	{
		private ILifeCycleContainer internalContainer;
		private IPerRequestLifeCycleContainerProvider perRequestLifecycleContainerProvider;

		public object RetrieveObject(IExportStrategy strategy,
		                             ExportLifeCycleMethod exportMethod,
		                             IDependencyInjectionContainer container,
		                             IInjectionContext injectionContext,
		                             object[] constructorParams)
		{
			if (internalContainer != null)
			{
				return internalContainer.RetrieveObject(strategy, exportMethod, container, injectionContext, constructorParams);
			}

			if (perRequestLifecycleContainerProvider == null)
			{
				perRequestLifecycleContainerProvider = container.Locate<IPerRequestLifeCycleContainerProvider>();
			}

			if (perRequestLifecycleContainerProvider != null)
			{
				internalContainer = perRequestLifecycleContainerProvider.ProvideContainer();
			}

			if (internalContainer != null)
			{
				return internalContainer.RetrieveObject(strategy, exportMethod, container, injectionContext, constructorParams);
			}

			internalContainer = new SharedPerInjectionContainer();

			return internalContainer.RetrieveObject(strategy, exportMethod, container, injectionContext, constructorParams);
		}

		public void Shutdown()
		{
			internalContainer.Shutdown();
		}
	}
}